#ifndef __QAHOLOM_H__
#define __QAHOLOM_H__

#include <stdio.h>
#include <gtk/gtk.h>

#include <string>
#include <list>
#include <vector>

using namespace std;

class QahWidget;

/////////////////////////////////////////////////////////////////////////////////////////
// QahDUMMY  class declaration
// -- this class is used in only hierarchical construction to avoid multiple GTK+ objects
// -- creation.

class QahDUMMY 
{
public:
   char  dummy;
   
public:
   QahDUMMY() {}
};

/////////////////////////////////////////////////////////////////////////////////////////
// QahProperty class declaration

template <typename T>
class QahProperty
{
protected:
   GtkWidget* holder;  // 4 bytes
   char*      name;    // 4 bytes
protected:
   
public:
   QahProperty() {}
   QahProperty(GtkWidget* widget, const char* str) 
   {
      init(widget, str);
   }

   void init(GtkWidget* widget, const char* str) 
   {
      holder = widget;
      name   = const_cast<char*>(str);
   }
   
   T& operator = (const T& __val) 
   {
      g_object_set(holder, name, __val, NULL);
      return const_cast<T&>(__val);
   }
   
   operator T () 
   {
      T ret;
      g_object_get(holder, name, &ret, NULL);
      return ret; 
   }
   
};

/////////////////////////////////////////////////////////////////////////////////////////
// Qaholom UI Framework's root class

#define PROPERTY_INIT(A,B)    A.init(egoWidget, B)

class QahWidget 
{
public: // property members and operations
   QahProperty<gboolean>    visible;
   QahProperty<int>         heightRequest;
   QahProperty<int>         widthRequest;
   QahProperty<gboolean>    canFocus; 
   
   // QahProperty<GtkContainer*, QahContainer&>  parent;

   void __init_properties() 
   {
      PROPERTY_INIT(visible,       "visible");
      PROPERTY_INIT(heightRequest, "height-request");
      PROPERTY_INIT(widthRequest,  "width-request");
      PROPERTY_INIT(canFocus,      "can-focus");
      
      //visible.init(egoWidget, "visible");
      //heightRequest.init(egoWidget, "height-request");
      //widthRequest.init(egoWidget, "width-request");
      //canFocus.init(egoWidget, "can-focus");
   }

public:
   GtkWidget*  egoWidget;
   
public:
   QahWidget() 
   { 
      egoWidget = NULL; 
   }
   
   QahWidget(QahWidget& widget) { egoWidget = widget.egoWidget; }
   QahWidget(GtkWidget* widget) { egoWidget = widget; }
   ~QahWidget() {}
   
   void dispose() 
   { 
      if (egoWidget) gtk_widget_unref(egoWidget); 
   }
   
   QahWidget& operator = (QahWidget& widget) { egoWidget = widget.egoWidget; }
   operator GtkWidget* ()
   {
      return egoWidget; 
   }
   
public: // signal operations
   void signalConnect(const char* signal, void* param = NULL) 
   {
      //g_signal_connect(GTK_WIDGET(egoWidget), signal, 
      return;
   }
   
public: // property operations
   template <typename T> bool propertyAs(const char* _P, T& _V) 
   { return g_object_set(egoWidget, _P, _V, NULL); } 
   
   template <typename T1, typename T2> bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2) 
   { 
      return g_object_set(egoWidget, _P1, _V1, _P2, _V2, NULL); 
   }
   
   template <typename T1, typename T2, typename T3> 
   bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2, const char* _P3, T3 _V3) 
   { 
      return g_object_set(egoWidget, _P1, _V1, _P2, _V2, _P3, _V3, NULL); 
   }    
   
   template <typename T1, typename T2, typename T3, typename T4> 
   bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2, const char* _P3, T3 _V3, 
                   const char* _P4, T4 _V4) 
   { 
      g_object_set(GTK_OBJECT(egoWidget), _P1, _V1, _P2, _V2, _P3, _V3, _P4, _V4, NULL); 
      return true; 
   }    
   
   template <typename T1, typename T2, typename T3, typename T4, typename T5> 
   bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2, const char* _P3, T3 _V3, 
                   const char* _P4, T4 _V4, const char* _P5, T5 _V5) 
   { 
      return g_object_set(egoWidget, _P1, _V1, _P2, _V2, _P3, _V3, _P4, _V4, _P5, _V5, NULL); 
   }    
   
   template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 
   bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2, const char* _P3, T3 _V3, 
                   const char* _P4, T4 _V4, const char* _P5, T5 _V5, const char* _P6, T6 _V6) 
   { 
      return g_object_set(egoWidget, _P1, _V1, _P2, _V2, _P3, _V3, _P4, _V4, _P5, _V5, _P6, _V6, NULL); 
   }    
   
   template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 
   bool propertyAs(const char* _P1, T1 _V1, const char* _P2, T2 _V2, const char* _P3, T3 _V3, 
                   const char* _P4, T4 _V4, const char* _P5, T5 _V5, const char* _P6, T6 _V6, 
                   const char* _P7, T7 _V7) 
   { 
      return g_object_set(egoWidget, _P1, _V1, _P2, _V2, _P3, _V3, _P4, _V4, _P5, _V5, _P6, _V6, 
                          _P7, _V7, NULL); 
   }    
};


////////////////////////////////////////////////////////////////////////////////////////////////
// Some useful macros

#define VALID_QAHWIDGET(A)   (A.egoWidget != NULL)



#endif
